#include "stdafx.h"
#include "stdlib/exception.hpp"
#include <typeinfo>

namespace JHCPP
{
	namespace stdlib
	{
		CException::CException(int code)
		: m_pNested(0),
		m_code(code)
		{
		}

		CException::CException(const std::string& msg, int code)
		: m_msg(msg),
		m_pNested(0),
		m_code(code)
		{
		}

		CException::CException(const std::string& msg, const std::string& arg, int code)
		: m_msg(msg),
		m_pNested(0),
		m_code(code)
		{
			if (!arg.empty())
			{
				m_msg.append(": ");
				m_msg.append(arg);
			}
		}

		CException::CException(const std::string& msg, const CException& nested, int code)
		: m_msg(msg),
		m_pNested(nested.clone()),
		m_code(code)
		{
		}

		CException::CException(const CException& exc)
		: std::exception(exc),
		m_msg(exc.m_msg),
		m_code(exc.m_code)
		{
			m_pNested = exc.m_pNested ? exc.m_pNested->clone() : 0;
		}

		CException::~CException() throw()
		{
			delete m_pNested;
			m_pNested = 0;
		}

		CException& CException::operator = (const CException& exc)
		{
			if (&exc != this)
			{
				delete m_pNested;
				m_pNested = 0;
				m_msg     = exc.m_msg;
				m_pNested = exc.m_pNested ? exc.m_pNested->clone() : 0;
				m_code    = exc.m_code;
			}
			return *this;
		}

		const char* CException::name() const throw()
		{
			return "CException";
		}

		const char* CException::className() const throw()
		{
			return typeid(*this).name();
		}

		const char* CException::what() const throw()
		{
			return name();
		}

		const CException* CException::nested() const
		{
			return m_pNested;
		}

		const std::string& CException::message() const
		{
			return m_msg;
		}

		void CException::message(const std::string& msg)
		{
			m_msg = msg;
		}

		int CException::code() const
		{
			return m_code;
		}

		std::string CException::displayText() const
		{
			std::string txt = name();
			if (!m_msg.empty())
			{
				txt.append(": ");
				txt.append(m_msg);
			}
			return txt;
		}

		void CException::extendedMessage(const std::string& arg)
		{
			if (!arg.empty())
			{
				if (!m_msg.empty()) m_msg.append(": ");
				m_msg.append(arg);
			}
		}

		CException* CException::clone() const
		{
			return new CException(*this);
		}

		void CException::rethrow() const
		{
			throw *this;
		}


		namespace jhException
		{
			JH_IMPLEMENT_EXCEPTION(LogicException, CException, "Logic exception")
			JH_IMPLEMENT_EXCEPTION(AssertionViolationException, LogicException, "Assertion violation")
			JH_IMPLEMENT_EXCEPTION(NullPointerException, LogicException, "Null pointer")
			JH_IMPLEMENT_EXCEPTION(NullValueException, LogicException, "Null value")
			JH_IMPLEMENT_EXCEPTION(BugcheckException, LogicException, "Bugcheck")
			JH_IMPLEMENT_EXCEPTION(InvalidArgumentException, LogicException, "Invalid argument")
			JH_IMPLEMENT_EXCEPTION(NotImplementedException, LogicException, "Not implemented")
			JH_IMPLEMENT_EXCEPTION(RangeException, LogicException, "Out of range")
			JH_IMPLEMENT_EXCEPTION(IllegalStateException, LogicException, "Illegal state")
			JH_IMPLEMENT_EXCEPTION(InvalidAccessException, LogicException, "Invalid access")
			JH_IMPLEMENT_EXCEPTION(SignalException, LogicException, "Signal received")
			JH_IMPLEMENT_EXCEPTION(UnhandledException, LogicException, "Unhandled exception")

			JH_IMPLEMENT_EXCEPTION(RuntimeException, CException, "Runtime exception")
			JH_IMPLEMENT_EXCEPTION(NotFoundException, RuntimeException, "Not found")
			JH_IMPLEMENT_EXCEPTION(ExistsException, RuntimeException, "Exists")
			JH_IMPLEMENT_EXCEPTION(TimeoutException, RuntimeException, "Timeout")
			JH_IMPLEMENT_EXCEPTION(SystemException, RuntimeException, "System exception")
			JH_IMPLEMENT_EXCEPTION(RegularExpressionException, RuntimeException, "Error in regular expression")
			JH_IMPLEMENT_EXCEPTION(LibraryLoadException, RuntimeException, "Cannot load library")
			JH_IMPLEMENT_EXCEPTION(LibraryAlreadyLoadedException, RuntimeException, "Library already loaded")
			JH_IMPLEMENT_EXCEPTION(NoThreadAvailableException, RuntimeException, "No thread available")
			JH_IMPLEMENT_EXCEPTION(PropertyNotSupportedException, RuntimeException, "Property not supported")
			JH_IMPLEMENT_EXCEPTION(PoolOverflowException, RuntimeException, "Pool overflow")
			JH_IMPLEMENT_EXCEPTION(NoPermissionException, RuntimeException, "No permission")
			JH_IMPLEMENT_EXCEPTION(OutOfMemoryException, RuntimeException, "Out of memory")
			JH_IMPLEMENT_EXCEPTION(DataException, RuntimeException, "Data error")

			JH_IMPLEMENT_EXCEPTION(DataFormatException, DataException, "Bad data format")
			JH_IMPLEMENT_EXCEPTION(SyntaxException, DataException, "Syntax error")
			JH_IMPLEMENT_EXCEPTION(CircularReferenceException, DataException, "Circular reference")
			JH_IMPLEMENT_EXCEPTION(PathSyntaxException, SyntaxException, "Bad path syntax")
			JH_IMPLEMENT_EXCEPTION(IOException, RuntimeException, "I/O error")
			JH_IMPLEMENT_EXCEPTION(ProtocolException, IOException, "Protocol error")
			JH_IMPLEMENT_EXCEPTION(FileException, IOException, "File access error")
			JH_IMPLEMENT_EXCEPTION(FileExistsException, FileException, "File exists")
			JH_IMPLEMENT_EXCEPTION(FileNotFoundException, FileException, "File not found")
			JH_IMPLEMENT_EXCEPTION(PathNotFoundException, FileException, "Path not found")
			JH_IMPLEMENT_EXCEPTION(FileReadOnlyException, FileException, "File is read-only")
			JH_IMPLEMENT_EXCEPTION(FileAccessDeniedException, FileException, "Access to file denied")
			JH_IMPLEMENT_EXCEPTION(CreateFileException, FileException, "Cannot create file")
			JH_IMPLEMENT_EXCEPTION(OpenFileException, FileException, "Cannot open file")
			JH_IMPLEMENT_EXCEPTION(WriteFileException, FileException, "Cannot write file")
			JH_IMPLEMENT_EXCEPTION(ReadFileException, FileException, "Cannot read file")
			JH_IMPLEMENT_EXCEPTION(UnknownURISchemeException, RuntimeException, "Unknown URI scheme")

			JH_IMPLEMENT_EXCEPTION(ApplicationException, CException, "Application exception")
			JH_IMPLEMENT_EXCEPTION(BadCastException, RuntimeException, "Bad cast exception")
		}//end of namespace jhException

	}//end of namespace stdlib
}//end of namespace JHCPP
